package midware

import (
	"github.com/gin-gonic/gin"
	"shop/config/constant"
	"shop/entity"
	"shop/utils/convertutil"
	"shop/utils/jwtutil"
	"shop/utils/result"
	"shop/utils/sessionutil"
)

// Auth authenticate and authorize
func Auth() gin.HandlerFunc {
	return func(c *gin.Context) {
		token := c.Query(constant.ParamToken)
		if token == "" {
			token = c.GetHeader(constant.ParamToken)
		}
		// seelog.Debug("verifyToken, token=" + token)
		if token != "" {
			jwtClaims, isValid := jwtutil.ParseToken(token)
			if isValid && jwtClaims.UserId != 0 && sessionutil.CheckLogin(jwtClaims.UserId) {
				jwtClaims.Refresh(c) // 检查是否需要续期
				c.Set(constant.ParamUserId, jwtClaims.UserId)
				c.Set(constant.ParamShopId, jwtClaims.ShopId)
				c.Next()
				return
			}
		}
		result.RenderResult(c, result.Fail("user not login").SetCode(result.ErrCodeNotLogin))
		c.Abort()
	}
}

// AdminAuth authenticate and authorize, 后台管理
func AdminAuth(permissions ...string) gin.HandlerFunc {
	return func(c *gin.Context) {
		token := c.Query(constant.ParamToken)
		if token == "" {
			token = c.GetHeader(constant.ParamToken)
		}
		// seelog.Debug("verifyToken, token=" + token)
		if token != "" {
			jwtClaims, isValid := jwtutil.ParseToken(token)
			if isValid && jwtClaims.UserId != 0 && sessionutil.CheckAdminLogin(jwtClaims.UserId) {
				jwtClaims.Refresh(c) // 检查是否需要续期
				c.Set(constant.ParamSysUserId, jwtClaims.UserId)
				c.Set(constant.ParamShopId, jwtClaims.ShopId)
				user := sessionutil.GetSysUserInfo(jwtClaims.UserId)
				if !checkPermission(user, permissions) {
					result.RenderResult(c, result.Fail("权限不足："+convertutil.ToJsonString(permissions)).SetCode(result.ErrCodeNoPermission))
					c.Abort()
					return
				}
				c.Next()
				return
			}
		}
		result.RenderResult(c, result.Fail("sysUser not login").SetCode(result.ErrCodeNotLogin))
		c.Abort()
	}
}

func checkPermission(user *entity.SysUser, needPermissions []string) bool {
	if user.PermissionSet["*"] != nil {
		return true
	}
	for _, permission := range needPermissions {
		if permission != "" && user.PermissionSet[permission] == nil {
			return false
		}
	}
	return true
}
